//bubble_sort全类型,降序排列
//未完成
#include<stdio.h>
#include<string.h>
struct stu{
    char name[20];
    int age;
};
int cmp(const void*r1,const void*r2){
    return *(int*)r2-*(int*)r1;     //整型指针解引用       //第一个大于第二个,>0,第二个排到第一个前面去,升序
}                                                       //同理,当第一个与第二个交换位置后,也>0,交换位置，降序

int cmpp(const void*r1,const void*r2){
    return *(float*)r2-*(float*)r1;
}

int cmpage(const void*r1,const void*r2){
    return ((struct stu*)r2)->age - ((struct stu*)r1)->age;
}
int cmpname(const void*r1,const void*r2){
    //比较名字就是比较字符串，字符串比较不能直接用><=比较，应用strcmp函数
    return strcmp(((struct stu*)r2)->name,((struct stu*)r1)->name);
};

void swap(char* r1,char*r2,int width){
    int i=0;
    char temp=0;//注意这里temp要是char才方便接收char*的数据
    for(i=0;i<width;i++){
        temp=*r1;
        *r1=*r2;
        *r2=temp;
        r1++;         //不要忘记++,注意循环结束条件
        r2++;
    }
}
void bubble_sort(void* arr,int sz,int width,int (*cmp)(const void* r1,const void* r2)){//void*类型的指针可以接受任意类型的地址，并且不能进行解引用操作，
                                                                                       //还不能进行加减整数的操作
    int i=0;
    //趟数:
    for (i = 0; i < sz-1; i++) {//减一是因为会额外多排序一个
        //一趟冒泡排序
        int j=0;
        for (j = 0; j < sz-1-i; j++) {//减的i就是已经被交换过的，已经排到后面去了
            if(cmp((char*)arr+j*width,(char*)arr+(j+1)*width)>0){   //">0"代表的是第一个元素大于第二个元素
                swap((char*)arr+j*width,(char*)arr+(j+1)*width,width);//使用char*是为了方便单个字符单个字符地交换
            }
        }
    }
}
int main(){
    int arr[]={1,2,3,4,5,6,7,8,9};
    int sz=sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr,sz,sizeof(arr[0]),cmp);
    int i=0;
    for (i = 0; i <sz ; i++) {
        printf("%d ",arr[i]);
    }
    printf("\n");



    char arr1[] = { 'a','f','y','w','b' };
    bubble_sort(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(arr1[0]), cmp);
    for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
    {
        printf("%c ", arr1[i]);
    }
    printf("\n");

    struct stu s[3]={{"zhangyang",22},{"wangshaolong",20},{"chengming",21}};
    int sz2=sizeof(s)/sizeof(s[0]);
    bubble_sort(s,sz2,sizeof(s[0]),cmpage);
    //第一个参数:待排序数组的首元素地址
    //第二个参数:待排序数组的元素个数
    //第三个参数:待排序数组的每个元素的大小-单位是字节
    //第四个参数:函数指针，比较两个元素所用函数的地址-这个函数使用者自己实现，函数指针的两个参数是:待比较的两个元素的地址
    for(i=0;i<sz2;i++){
        printf("%s ",s[i]);
    }
    printf("\n");

    bubble_sort(s,sz2,sizeof(s[0]),cmpname);
    for(i=0;i<sz2;i++){
        printf("%s ",s[i]);
    }
    printf("\n");

    float arr2[]={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
    int sz3=sizeof(arr2)/sizeof(arr2[0]);
    bubble_sort(arr2,sz3,sizeof(arr2[0]),cmpp);
    for (i = 0; i <sz3 ; i++) {
        printf("%.2f ",arr2[i]);
    }
    return 0;
}